﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace DoAn
{
    public enum WindowState { Starting, Active, Ending, Inactive };
    class MenuWindow
    {
        private struct MenuItem
        {
            public Texture2D itemText;
            public MenuWindow itemLink;
            public Texture2D itemSlect;

            public MenuItem(Texture2D itemText, Texture2D itemSlect, MenuWindow itemLink)
            {
                this.itemText = itemText;
                this.itemSlect = itemSlect;
                this.itemLink = itemLink;
            }
        }

        private TimeSpan timeSpan;
        private WindowState windowState;
        private List<MenuItem> itemList;
        private int selectedItem;
        private double changeProgress;

        private SpriteFont spriteFont;
        private Texture2D nameTitle;
        private Texture2D bgImg;


        public MenuWindow(SpriteFont spriteFont, Texture2D nameTitle, Texture2D bgImg)
        {
            itemList = new List<MenuItem>();
            timeSpan = TimeSpan.FromMilliseconds(800);
            selectedItem = 0;
            changeProgress = 0;
            windowState = WindowState.Inactive;

            this.spriteFont = spriteFont;
            this.nameTitle = nameTitle;
            this.bgImg = bgImg;
        }

        public void AddMenuItem(Texture2D itemText, Texture2D itemSlect, MenuWindow itemLink)
        {
            MenuItem newItem = new MenuItem(itemText, itemSlect, itemLink);
            itemList.Add(newItem);
        }

        public void ActiveWindow()
        {
            windowState = WindowState.Starting;
        }

        public void Update(double timePassedSinceLastFrame)
        {
            if ((windowState == WindowState.Starting) || (windowState == WindowState.Ending))
                changeProgress += timePassedSinceLastFrame / timeSpan.TotalMilliseconds;

            if (changeProgress >= 1.0f)
            {
                changeProgress = 0.0f;

                if (windowState == WindowState.Starting)
                    windowState = WindowState.Active;
                else if (windowState == WindowState.Ending)
                    windowState = WindowState.Inactive;
            }
        }

        public MenuWindow ProcessInput(KeyboardState lastKbState, KeyboardState currKbState,
            GamePadState lastGPState, GamePadState currGPState)
        {
            if (lastKbState.IsKeyUp(Keys.Down) && currKbState.IsKeyDown(Keys.Down))
                ++selectedItem;

            if (lastKbState.IsKeyUp(Keys.Up) && currKbState.IsKeyDown(Keys.Up))
                --selectedItem;

            if ((lastGPState.DPad.Down == ButtonState.Released)
                && (currGPState.DPad.Down == ButtonState.Pressed))
                ++selectedItem;

            if ((lastGPState.DPad.Up == ButtonState.Released)
                && (currGPState.DPad.Up == ButtonState.Pressed))
                --selectedItem;

            if (selectedItem < 0)
                selectedItem = itemList.Count - 1;

            if (selectedItem >= itemList.Count)
                selectedItem = 0;

            if ((lastKbState.IsKeyUp(Keys.Enter) && currKbState.IsKeyDown(Keys.Enter))
                || ((lastGPState.Buttons.A == ButtonState.Released)
                    && (currGPState.Buttons.A == ButtonState.Pressed)))
            {
                windowState = WindowState.Ending;
                if(itemList.Count > 0)
                    return itemList[selectedItem].itemLink;
                return this;
            }
            else if (lastKbState.IsKeyDown(Keys.Q))
                return null;

            return this;
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            if (windowState == WindowState.Inactive)
                return;

            float smoothProgress = MathHelper.SmoothStep(0, 1, (float)changeProgress);
            float vertPos = 300;
            float horPos = 300;
            float alphaValue;
            Color bgColor;

            switch (windowState)
            {
                case WindowState.Starting:
                    horPos -= 200 * (1.0f - (float)smoothProgress);
                    alphaValue = smoothProgress;
                    bgColor = new Color(new Vector4(1, 1, 1, alphaValue));
                    break;
                case WindowState.Ending:
                    horPos += 200 * (float)smoothProgress;
                    alphaValue = 1.0f - smoothProgress;
                    bgColor = Color.White;
                    break;
                default:
                    alphaValue = 1;
                    bgColor = Color.White;
                    break;
            }

            Color colorTitle = new Color(new Vector4(1, 1, 1, alphaValue));
            spriteBatch.Draw(bgImg, new Vector2(), null, bgColor, 0,
                Vector2.Zero, 1, SpriteEffects.None, 0);
            spriteBatch.Draw(nameTitle, new Vector2(horPos - 40, vertPos - 75), colorTitle);

            for (int idItem = 0; idItem < itemList.Count; ++idItem)
            {
                Vector2 posItem = new Vector2(horPos, vertPos);
                Color colorItem = Color.White;

                if (idItem == selectedItem)
                {
                    spriteBatch.Draw(itemList[idItem].itemSlect, posItem, colorItem);
                }
                else
                {
                    spriteBatch.Draw(itemList[idItem].itemText, posItem, colorItem);
                }
                vertPos += 40;
            }
        }
    }
}